/* 鏂囦欢锛� w25flash.c
 * 鍔熻兘鎻忚堪锛� Flash 瀛樺偍鍣╓25Q128鐨勯┍鍔ㄧ▼搴�
 * 浣滆�咃細鐜嬬淮娉�
 * 淇敼鏃ユ湡锛�2019-06-05
 */

#include "w25flash.h"

#define MAX_TIMEOUT   200		//SPI杞鎿嶄綔鏃剁殑鏈�澶х瓑寰呮椂闂�,ms

//SPI鎺ュ彛鍙戦�佷竴涓瓧鑺�,byteData鏄渶瑕佸彂閫佺殑鏁版嵁
HAL_StatusTypeDef SPI_TransmitOneByte(uint8_t byteData) {
	return HAL_SPI_Transmit(&SPI_HANDLE, &byteData, 1, MAX_TIMEOUT);
}

//SPI鎺ュ彛鍙戦�佸涓瓧鑺�, pBuffer鏄彂閫佹暟鎹紦瀛樺尯鎸囬拡锛宐yteCount鏄彂閫佹暟鎹瓧鑺傛暟锛宐yteCount鏈�澶�256
HAL_StatusTypeDef SPI_TransmitBytes(uint8_t *pBuffer, uint16_t byteCount) {
	return HAL_SPI_Transmit(&SPI_HANDLE, pBuffer, byteCount, MAX_TIMEOUT);
}
//SPI鎺ュ彛鍙戦�佸涓瓧鑺�, pBuffer鏄彂閫佹暟鎹紦瀛樺尯鎸囬拡锛宐yteCount鏄彂閫佹暟鎹瓧鑺傛暟锛宐yteCount鏈�澶�256
HAL_StatusTypeDef SPI_TransmitBytesDMA(uint8_t *pBuffer, uint16_t byteCount) {
	return HAL_SPI_Transmit_DMA(&SPI_HANDLE, pBuffer, byteCount);
}

//SPI鎺ュ彛鎺ユ敹涓�涓瓧鑺傦紝 杩斿洖鎺ユ敹鐨勪竴涓瓧鑺傛暟鎹�
uint8_t SPI_ReceiveOneByte() {
	uint8_t byteData = 0;
	HAL_SPI_Receive(&SPI_HANDLE, &byteData, 1, MAX_TIMEOUT);
	return byteData;
}

//SPI鎺ュ彛鎺ユ敹澶氫釜瀛楄妭锛� pBuffer鏄帴鏀舵暟鎹紦瀛樺尯鎸囬拡锛宐yteCount鏄渶瑕佹帴鏀舵暟鎹殑瀛楄妭鏁�
HAL_StatusTypeDef SPI_ReceiveBytes(uint8_t *pBuffer, uint16_t byteCount) {
	return HAL_SPI_Receive(&SPI_HANDLE, pBuffer, byteCount, MAX_TIMEOUT);
}
//SPI鎺ュ彛鎺ユ敹澶氫釜瀛楄妭锛� pBuffer鏄帴鏀舵暟鎹紦瀛樺尯鎸囬拡锛宐yteCount鏄渶瑕佹帴鏀舵暟鎹殑瀛楄妭鏁�
HAL_StatusTypeDef SPI_ReceiveBytesDMA(uint8_t *pBuffer, uint16_t byteCount) {
	return HAL_SPI_Receive_DMA(&SPI_HANDLE, pBuffer, byteCount);
}

//Command=0x05:  Read Status Register-1,杩斿洖瀵勫瓨鍣⊿R1鐨勫��
uint8_t Flash_ReadSR1(void) {
	uint8_t byte = 0;
	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x05); //Command=0x05:  Read Status Register-1
	byte = SPI_ReceiveOneByte();
	__Deselect_Flash();	//CS=1
	return byte;
}

//Command=0x35:  Read Status Register-2,杩斿洖瀵勫瓨鍣⊿R2鐨勫��
uint8_t Flash_ReadSR2(void) {
	uint8_t byte = 0;
	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x35); //Command=0x35:  Read Status Register-2
	byte = SPI_ReceiveOneByte();	//璇诲彇涓�涓瓧鑺�
	__Deselect_Flash();	//CS=1
	return byte;
}

//Command=0x01:  Write Status Register,	鍙啓SR1鐨勫��
//鑰楁椂澶х害10-15ms
void Flash_WriteSR1(uint8_t SR1) {
	Flash_Write_Enable();       //蹇呴』浣� WEL=1

	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x01); //Command=0x01:  Write Status Register,	鍙啓SR1鐨勫��
	SPI_TransmitOneByte(0x00);    //SR1鐨勫��
//	SPI_WriteOneByte(0x00);    //SR2鐨勫��, 鍙彂閫丼R1鐨勫�硷紝鑰屼笉鍙戦�丼R2鐨勫�硷紝 QE鍜孋MP灏嗚嚜鍔ㄨ娓呴浂
	__Deselect_Flash();	//CS=1

	Flash_Wait_Busy(); 	   //鑰楁椂澶х害10-15ms
}

HAL_StatusTypeDef Flash_WriteVolatile_Enable(void) //Command=0x50: Write Volatile Enable
{
	__Select_Flash();	//CS=0
	HAL_StatusTypeDef result = SPI_TransmitOneByte(0x50);
	__Deselect_Flash();	//CS=1
	return result;
}

//Command=0x06: Write Enable,    浣縒EL=1
HAL_StatusTypeDef Flash_Write_Enable(void) {
	__Select_Flash();	//CS=0
	HAL_StatusTypeDef result = SPI_TransmitOneByte(0x06); //Command=0x06: Write Enable,    浣縒EL=1
	__Deselect_Flash();	//CS=1
	Flash_Wait_Busy(); 	//绛夊緟鎿嶄綔瀹屾垚
	return result;
}

//Command=0x04, Write Disable锛�	  浣縒EL=0
HAL_StatusTypeDef Flash_Write_Disable(void) {
	__Select_Flash();	//CS=0
	HAL_StatusTypeDef result = SPI_TransmitOneByte(0x04); //Command=0x04, Write Disable锛�	  浣縒EL=0
	__Deselect_Flash();	//CS=1
	Flash_Wait_Busy(); 	   //
	return result;
}

//鏍规嵁Block缁濆缂栧彿鑾峰彇鍦板潃, 鍏�256涓狟lock锛� BlockNo 鍙栧�艰寖鍥�0-255
//姣忎釜鍧�64K瀛楄妭锛�16浣嶅湴鍧�锛屽潡鍐呭湴鍧�鑼冨洿0x0000-0xFFFF銆�
uint32_t Flash_Addr_byBlock(uint8_t BlockNo) {
//	uint32_t addr=BlockNo*0x10000;

	uint32_t addr = BlockNo;
	addr = addr << 16; //宸︾Щ16浣嶏紝绛変簬涔樹互0x10000
	return addr;
}

//鏍规嵁Sector缁濆缂栧彿鑾峰彇鍦板潃, 鍏�4096涓猄ector, SectorNo鍙栧�艰寖鍥�0-4095
//姣忎釜鎵囧尯4K瀛楄妭锛�12浣嶅湴鍧�锛屾墖鍖哄唴鍦板潃鑼冨洿0x000-0xFFF
uint32_t Flash_Addr_bySector(uint16_t SectorNo) {
	if (SectorNo > 4095)	//涓嶈兘瓒呰繃4095
		SectorNo = 0;
//	uint32_t addr=SectorNo*0x1000;

	uint32_t addr = SectorNo;
	addr = addr << 12;		//宸︾Щ12浣�,绛変簬涔樹互0x1000
	return addr;
}

//鏍规嵁Page缁濆缂栧彿鑾峰彇鍦板潃锛屽叡65536涓狿age,  PageNo鍙栧�艰寖鍥�0-65535
//姣忎釜椤�256瀛楄妭锛�8浣嶅湴鍧�锛岄〉鍐呭湴鍧�鑼冨洿0x00鈥�0xFF
uint32_t Flash_Addr_byPage(uint16_t PageNo) {
//	uint32_t addr=PageNo*0x100;

	uint32_t addr = PageNo;
	addr = addr << 8;		//宸︾Щ8浣嶏紝绛変簬涔樹互0x100
	return addr;
}

//鏍规嵁Block缂栧彿鍜屽唴閮⊿ector缂栧彿璁＄畻鍦板潃锛屼竴涓狟lock鏈�16涓猄ector
//BlockNo鍙栧�艰寖鍥�0-255锛�  鍐呴儴SubSectorNo鍙栧�艰寖鍥�0-15
uint32_t Flash_Addr_byBlockSector(uint8_t BlockNo, uint8_t SubSectorNo) {
	if (SubSectorNo > 15)	 //涓嶈兘瓒呰繃15
		SubSectorNo = 0;

//	uint32_t addr=BlockNo*0x10000;	//鍏堣绠桞lock鐨勮捣濮嬪湴鍧�
	uint32_t addr = BlockNo;
	addr = addr << 16;	//鍏堣绠桞lock鐨勮捣濮嬪湴鍧�

//	uint32_t offset=SubSectorNo*0x1000;	//璁＄畻Sector鐨勫亸绉诲湴鍧�
	uint32_t offset = SubSectorNo;	//璁＄畻Sector鐨勫亸绉诲湴鍧�
	offset = offset << 12;	//璁＄畻Sector鐨勫亸绉诲湴鍧�

	addr += offset;

	return addr;
}

//鏍规嵁Block缂栧彿锛屽唴閮⊿ector缂栧彿锛屽唴閮≒age缂栧彿鑾峰彇鍦板潃
//BlockNo鍙栧�艰寖鍥�0-255
//涓�涓狟lock鏈�16涓猄ector锛� 鍐呴儴SubSectorNo鍙栧�艰寖鍥�0-15
//涓�涓猄ector鏈�16涓狿age , 鍐呴儴SubPageNo鍙栧�艰寖鍥�0-15
uint32_t Flash_Addr_byBlockSectorPage(uint8_t BlockNo, uint8_t SubSectorNo,
		uint8_t SubPageNo) {
	if (SubSectorNo > 15)	//涓嶈兘瓒呰繃15
		SubSectorNo = 0;

	if (SubPageNo > 15)	//涓嶈兘瓒呰繃15
		SubPageNo = 0;

//	uint32_t addr=BlockNo*0x10000;		//鍏堣绠桞lock鐨勮捣濮嬪湴鍧�
	uint32_t addr = BlockNo;
	addr = addr << 16;		//鍏堣绠桞lock鐨勮捣濮嬪湴鍧�

//	uint32_t offset=SubSectorNo*0x1000;	//璁＄畻Sector鐨勫亸绉诲湴鍧�
	uint32_t offset = SubSectorNo;	//璁＄畻Sector鐨勫亸绉诲湴鍧�
	offset = offset << 12;	//璁＄畻Sector鐨勫亸绉诲湴鍧�
	addr += offset;

//	offset=SubPageNo*0x100;	//璁＄畻Page鐨勫亸绉诲湴鍧�
	offset = SubPageNo;
	offset = offset << 8;	//璁＄畻Page鐨勫亸绉诲湴鍧�

	addr += offset;		//Page鐨勮捣濮嬪湴鍧�
	return addr;
}

//灏�24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�
//globalAddr鏄叏灞�24浣嶅湴鍧�, 杩斿洖 addrHigh楂樺瓧鑺傦紝addrMid涓棿瀛楄妭锛宎ddrLow浣庡瓧鑺�
void Flash_SpliteAddr(uint32_t globalAddr, uint8_t *addrHigh, uint8_t *addrMid,
		uint8_t *addrLow) {
	*addrHigh = (globalAddr >> 16);	//addrHigh=楂樺瓧鑺�

	globalAddr = globalAddr & 0x0000FFFF;	//灞忚斀楂樺瓧鑺�
	*addrMid = (globalAddr >> 8);	//addrMid=涓棿瀛楄妭

	*addrLow = globalAddr & 0x000000FF;	//灞忚斀涓棿瀛楄妭锛� 鍙墿浣庡瓧鑺傦紝addrLow=浣庡瓧鑺�
}

//璇诲彇鑺墖ID
//杩斿洖鍊煎涓�:
// 0xEF17,琛ㄧず鑺墖鍨嬪彿涓篧25Q128, Winbond,鐢ㄨ繃
// 0xC817锛岃〃绀鸿姱鐗囧瀷鍙蜂负GD25Q128,ELM锛岀敤杩�
// 0x1C17锛岃〃绀鸿姱鐗囧瀷鍙蜂负EN25Q128,鍙版咕EON
// 0xA117锛岃〃绀鸿姱鐗囧瀷鍙蜂负FM25Q128锛屽鏃﹀井鐢靛瓙
// 0x2018锛岃〃绀鸿姱鐗囧瀷鍙蜂负N25Q128锛岀編鍏�
// 0x2017锛岃〃绀鸿姱鐗囧瀷鍙蜂负XM25QH128锛屾姹夋柊鑺紝鐢ㄨ繃

//璇诲彇鑺墖鐨勫埗閫犲晢鍜屽櫒浠禝D锛岄珮瀛楄妭鏄疢anufacturer ID,浣庡瓧鑺傛槸Device ID
uint16_t Flash_ReadID(void) {
	uint16_t Temp = 0;
	__Select_Flash();	//CS=0

	SPI_TransmitOneByte(0x90);		//鎸囦护鐮侊紝0x90=Manufacturer/Device ID
	SPI_TransmitOneByte(0x00);		//dummy
	SPI_TransmitOneByte(0x00);		//dummy
	SPI_TransmitOneByte(0x00);		//0x00
	Temp = SPI_ReceiveOneByte() << 8;	//Manufacturer ID
	Temp |= SPI_ReceiveOneByte();	 	//Device ID, 涓庡叿浣撳櫒浠剁浉鍏�

	__Deselect_Flash();	//CS=1
	return Temp;
}

// 鍙傛暟High32鍜孡ow32鍒嗗埆杩斿洖64浣嶅簭鍒楀彿鐨勯珮32浣嶅拰浣�32浣嶇殑鍊�
// 鍑芥暟杩斿洖鍊间负64浣嶅簭鍒楀彿鐨勫��
uint64_t Flash_ReadSerialNum(uint32_t *High32, uint32_t *Low32)	//璇诲彇64浣嶅簭鍒楀彿锛�
{
	uint8_t Temp = 0;
	uint64_t SerialNum = 0;
	uint32_t High = 0, Low = 0;

	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x4B);		//鍙戦�佹寚浠ょ爜, 4B=read Unique ID
	SPI_TransmitOneByte(0x00);		//鍙戦��4涓狣ummy瀛楄妭鏁版嵁
	SPI_TransmitOneByte(0x00);
	SPI_TransmitOneByte(0x00);
	SPI_TransmitOneByte(0x00);

	for (uint8_t i = 0; i < 4; i++)  //楂�32浣�
			{
		Temp = SPI_ReceiveOneByte();
		High = (High << 8);
		High = High | Temp;  //鎸変綅鎴�
	}

	for (uint8_t i = 0; i < 4; i++)	//浣�32浣�
			{
		Temp = SPI_ReceiveOneByte();
		Low = (Low << 8);
		Low = Low | Temp;  //鎸変綅鎴�
	}
	__Deselect_Flash();	//CS=1

	*High32 = High;
	*Low32 = Low;

	SerialNum = High;
	SerialNum = SerialNum << 32;  //楂�32浣�
	SerialNum = SerialNum | Low;

	return SerialNum;
}

//鍦ㄤ换鎰忓湴鍧�璇诲彇涓�涓瓧鑺傜殑鏁版嵁,杩斿洖璇诲彇鐨勫瓧鑺傛暟鎹�
// globalAddr鏄�24浣嶅叏灞�鍦板潃
uint8_t Flash_ReadOneByte(uint32_t globalAddr) {
	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x03);      //Command=0x03, read data
	SPI_TransmitOneByte(byte2);		//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);
	byte2 = SPI_ReceiveOneByte();	//鎺ユ敹1涓瓧鑺�
	__Deselect_Flash();	//CS=1

	return byte2;
}

//浠庝换浣曞湴鍧�寮�濮嬭鍙栨寚瀹氶暱搴︾殑鏁版嵁
//globalAddr锛氬紑濮嬭鍙栫殑鍦板潃(24bit)锛� pBuffer锛氭暟鎹瓨鍌ㄥ尯鎸囬拡锛宐yteCount:瑕佽鍙栫殑瀛楄妭鏁�
void Flash_ReadBytes(uint32_t globalAddr, uint8_t *pBuffer, uint16_t byteCount) {
	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x03);      //Command=0x03, read data
	SPI_TransmitOneByte(byte2);		//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);
	SPI_ReceiveBytes(pBuffer, byteCount);	//鎺ユ敹byteCount涓瓧鑺傛暟鎹�
	__Deselect_Flash();	//CS=1
}
//浠庝换浣曞湴鍧�寮�濮嬭鍙栨寚瀹氶暱搴︾殑鏁版嵁
//globalAddr锛氬紑濮嬭鍙栫殑鍦板潃(24bit)锛� pBuffer锛氭暟鎹瓨鍌ㄥ尯鎸囬拡锛宐yteCount:瑕佽鍙栫殑瀛楄妭鏁�
void Flash_ReadBytesDMA(uint32_t globalAddr, uint8_t *pBuffer, uint16_t byteCount) {
	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x03);      //Command=0x03, read data
	SPI_TransmitOneByte(byte2);		//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);
	SPI_ReceiveBytesDMA(pBuffer, byteCount);	//鎺ユ敹byteCount涓瓧鑺傛暟鎹�
}

//Command=0x0B,  楂橀�熻繛缁鍙杅lash澶氫釜瀛楄妭锛屼换鎰忓叏灞�鍦板潃锛� 閫熷害澶х害鏄父瑙勮鍙栫殑2鍊�
void Flash_FastReadBytes(uint32_t globalAddr, uint8_t *pBuffer,
		uint16_t byteCount) {
// 	uint16_t i;
	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	__Select_Flash();	//CS=0

	SPI_TransmitOneByte(0x0B);      //Command=0x0B, fast read data
	SPI_TransmitOneByte(byte2);		//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);
	SPI_TransmitOneByte(0x00);		//Dummy瀛楄妭

	SPI_ReceiveBytes(pBuffer, byteCount);	//鎺ユ敹byteCount涓瓧鑺傛暟鎹�
	__Deselect_Flash();	//CS=1

}

//Command=0xC7: Chip Erase, 鎿﹂櫎鏁翠釜鍣ㄤ欢
// 鎿﹂櫎鍚庯紝鎵�鏈夊瓨鍌ㄥ尯鍐呭涓�0xFF,鑰楁椂澶х害25绉�
void Flash_EraseChip(void) {
	Flash_Write_Enable();   //浣� WEL=1
	Flash_Wait_Busy();   	//绛夊緟绌洪棽

	__Select_Flash();		//CS=0
	SPI_TransmitOneByte(0xC7);  // Command=0xC7: Chip Erase, 鎿﹂櫎鏁翠釜鍣ㄤ欢
	__Deselect_Flash();		//CS=1

	Flash_Wait_Busy();   //绛夊緟鑺墖鎿﹂櫎缁撴潫,澶х害25绉�
}

// Command=0x02: Page program, 瀵逛竴涓〉锛�256瀛楄妭锛夌紪绋�, 鑰楁椂澶х害3ms,
// globalAddr鏄啓鍏ュ垵濮嬪湴鍧�锛屽叏灞�鍦板潃
// pBuffer鏄鍐欏叆鏁版嵁缂撳啿鍖烘寚閽堬紝byteCount鏄渶瑕佸啓鍏ョ殑鏁版嵁瀛楄妭鏁�
// 鍐欏叆鐨凱age蹇呴』鏄墠闈㈠凡缁忔摝闄よ繃鐨勶紝濡傛灉鍐欏叆鍦板潃瓒呭嚭浜唒age鐨勮竟鐣岋紝灏变粠Page鐨勫紑澶撮噸鏂板啓
void Flash_WriteInPage(uint32_t globalAddr, uint8_t *pBuffer,
		uint16_t byteCount) {
	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	Flash_Write_Enable();   //SET WEL
	Flash_Wait_Busy();

	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x02);      //Command=0x02: Page program 瀵逛竴涓墖鍖虹紪绋�
	SPI_TransmitOneByte(byte2);	//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);
	SPI_TransmitBytes(pBuffer, byteCount); 		//鍙戦�乥yteCount涓瓧鑺傜殑鏁版嵁
//	for(uint16_t i=0; i<byteCount; i++)
//	{
//		byte2=pBuffer[i];
//		SPI_WriteOneByte(byte2);	//瑕佸啓鍏ョ殑鏁版嵁
//	}
	__Deselect_Flash();	//CS=1

	Flash_Wait_Busy(); 	   //鑰楁椂澶х害3ms
}
// Command=0x02: Page program, 瀵逛竴涓〉锛�256瀛楄妭锛夌紪绋�, 鑰楁椂澶х害3ms,
// globalAddr鏄啓鍏ュ垵濮嬪湴鍧�锛屽叏灞�鍦板潃
// pBuffer鏄鍐欏叆鏁版嵁缂撳啿鍖烘寚閽堬紝byteCount鏄渶瑕佸啓鍏ョ殑鏁版嵁瀛楄妭鏁�
// 鍐欏叆鐨凱age蹇呴』鏄墠闈㈠凡缁忔摝闄よ繃鐨勶紝濡傛灉鍐欏叆鍦板潃瓒呭嚭浜唒age鐨勮竟鐣岋紝灏变粠Page鐨勫紑澶撮噸鏂板啓
void Flash_WriteInPageDMA(uint32_t globalAddr, uint8_t *pBuffer,
		uint16_t byteCount) {
	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	Flash_Write_Enable();   //SET WEL
	Flash_Wait_Busy();

	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0x02);      //Command=0x02: Page program 瀵逛竴涓墖鍖虹紪绋�
	SPI_TransmitOneByte(byte2);	//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);
	SPI_TransmitBytesDMA(pBuffer, byteCount); 		//鍙戦�乥yteCount涓瓧鑺傜殑鏁版嵁
//	for(uint16_t i=0; i<byteCount; i++)
//	{
//		byte2=pBuffer[i];
//		SPI_WriteOneByte(byte2);	//瑕佸啓鍏ョ殑鏁版嵁
//	}



}

//浠庢煇涓猄ector鐨勮捣濮嬩綅缃紑濮嬪啓鏁版嵁锛屾暟鎹彲鑳借法瓒婂涓狿age,鐢氳嚦璺ㄨ秺Sector,涓嶅繀鎻愬墠鎿﹂櫎
// globalAddr鏄啓鍏ュ垵濮嬪湴鍧�锛屽叏灞�鍦板潃,鏄墖鍖虹殑璧峰鍦板潃锛�
// pBuffer鏄鍐欏叆鏁版嵁缂撳啿鍖烘寚閽�
// byteCount鏄渶瑕佸啓鍏ョ殑鏁版嵁瀛楄妭鏁帮紝byteCount涓嶈兘瓒呰繃64K锛屼篃灏辨槸涓�涓狟lock锛�16涓墖鍖猴級鐨勫ぇ灏�,浣嗘槸鍙互瓒呰繃涓�涓猄ector(4K瀛楄妭)
// 濡傛灉鏁版嵁瓒呰繃涓�涓狿age锛岃嚜鍔ㄥ垎鎴愬涓狿age锛岃皟鐢‥N25Q_WriteInPage鍒嗗埆鍐欏叆
void Flash_WriteSector(uint32_t globalAddr, const uint8_t *pBuffer,
		uint16_t byteCount) {
//闇�瑕佸厛鎿﹂櫎鎵囧尯锛屽彲鑳芥槸閲嶅鍐欐枃浠�
	uint8_t secCount = (byteCount / FLASH_SECTOR_SIZE);	//鏁版嵁瑕嗙洊鐨勬墖鍖轰釜鏁�
	if ((byteCount % FLASH_SECTOR_SIZE) > 0)
		secCount++;

	uint32_t startAddr = globalAddr;
	for (uint8_t k = 0; k < secCount; k++) {
		Flash_EraseSector(startAddr);	//鎿﹂櫎鎵囧尯
		startAddr += FLASH_SECTOR_SIZE;	//绉诲埌涓嬩竴涓墖鍖�
	}

//鍒嗘垚Page鍐欏叆鏁版嵁,鍐欏叆鏁版嵁鐨勬渶灏忓崟浣嶆槸Page
	uint16_t leftBytes = byteCount % FLASH_PAGE_SIZE; //闈炴暣鏁颁釜Page鍓╀綑鐨勫瓧鑺傛暟锛屽嵆鏈�鍚庝竴涓狿age鍐欏叆鐨勬暟鎹�
	uint16_t pgCount = byteCount / FLASH_PAGE_SIZE;  //鍓嶉潰鏁存暟涓狿age
	uint8_t *buff = pBuffer;
	for (uint16_t i = 0; i < pgCount; i++)	//鍐欏叆鍓嶉潰pgCount涓狿age鐨勬暟鎹紝
			{
		Flash_WriteInPage(globalAddr, buff, FLASH_PAGE_SIZE);  //鍐欎竴鏁翠釜Page鐨勬暟鎹�
		globalAddr += FLASH_PAGE_SIZE;	//鍦板潃绉诲姩涓�涓狿age
		buff += FLASH_PAGE_SIZE;		//鏁版嵁鎸囬拡绉诲姩涓�涓狿age澶у皬
	}

	if (leftBytes > 0)
		Flash_WriteInPage(globalAddr, buff, leftBytes); //鏈�鍚庝竴涓狿age锛屼笉鏄竴鏁翠釜Page鐨勬暟鎹�
}

//Command=0xD8: Block Erase(64KB) 鎿﹂櫎鏁翠釜Block, globalAddr鏄叏灞�鍦板潃
//娓呴櫎鍚庡瓨鍌ㄥ尯鍐呭鍏ㄩ儴涓�0xFF,  鑰楁椂澶ф150ms
void Flash_EraseBlock64K(uint32_t globalAddr) {
	Flash_Write_Enable();   //SET WEL
	Flash_Wait_Busy();

	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	__Select_Flash();	//CS=0

	SPI_TransmitOneByte(0xD8);      //Command=0xD8, Block Erase(64KB)
	SPI_TransmitOneByte(byte2);	//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);

	__Deselect_Flash();	//CS=1
	Flash_Wait_Busy(); 	   //鑰楁椂澶ф150ms
}

//鎿﹂櫎涓�涓墖鍖�(4KB瀛楄妭)锛孋ommand=0x20, Sector Erase(4KB)
//globalAddr: 鎵囧尯鐨勭粷瀵瑰湴鍧�锛�24浣嶅湴鍧�0x00XXXXXX
//鎿﹂櫎鍚庯紝鎵囧尯鍐呭叏閮ㄥ唴瀹逛负0xFF, 鑰楁椂澶х害30ms锛�
void Flash_EraseSector(uint32_t globalAddr) {
	Flash_Write_Enable();   //SET WEL
	Flash_Wait_Busy();
	uint8_t byte2, byte3, byte4;
	Flash_SpliteAddr(globalAddr, &byte2, &byte3, &byte4);	//24浣嶅湴鍧�鍒嗚В涓�3涓瓧鑺�

	__Select_Flash();	//CS=0

	SPI_TransmitOneByte(0x20);      //Command=0x20, Sector Erase(4KB)
	SPI_TransmitOneByte(byte2);		//鍙戦��24浣嶅湴鍧�
	SPI_TransmitOneByte(byte3);
	SPI_TransmitOneByte(byte4);

	__Deselect_Flash();		//CS=1
	Flash_Wait_Busy(); 	   //澶х害30ms
}

//妫�鏌ュ瘎瀛樺櫒SR1鐨凚USY浣嶏紝鐩村埌BUSY浣嶄负0
uint32_t Flash_Wait_Busy(void) {
	uint8_t SR1 = 0;
	uint32_t delay = 0;
	SR1 = Flash_ReadSR1();	//璇诲彇鐘舵�佸瘎瀛樺櫒SR1
	while ((SR1 & 0x01) == 0x01) {
		HAL_Delay(1);	//寤舵椂1ms
		delay++;
		SR1 = Flash_ReadSR1();	//璇诲彇鐘舵�佸瘎瀛樺櫒SR1
	}
	return delay;
}

//杩涘叆鎺夌數妯″紡
//Command=0xB9: Power Down
void Flash_PowerDown(void) {
	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0xB9);  //Command=0xB9: Power Down
	__Deselect_Flash();	//CS=1
	HAL_Delay(1); //绛夊緟TPD
}

//鍞ら啋
//Command=0xAB: Release Power Down
void Flash_WakeUp(void) {
	__Select_Flash();	//CS=0
	SPI_TransmitOneByte(0xAB);		//Command=0xAB: Release Power Down
	__Deselect_Flash();	//CS=1
	HAL_Delay(1);     //绛夊緟TRES1
}
